package com.gm.mygmc.crm.base;

import net.sf.oval.ConstraintViolation;
import net.sf.oval.exceptions.ConstraintsViolatedException;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class OperationHandler {

	Logger logger = LoggerFactory.getLogger(getClass());
	StringBuilder sb = new StringBuilder();	
	
	@Before("execution(* com.gm.mygmc.crm.*.service.*.*(..))")
	public Object autoLog(JoinPoint joinPoint) throws Throwable {
		
		sb.setLength(0);
		sb.append("\n[AOP_Autolog]");
		sb.append("Call method info : " + joinPoint.toLongString());
		sb.append("Parameters : \n");
		
		Object[] parameters = joinPoint.getArgs();
		if(parameters != null && parameters.length > 0){
			int i = 0;
			for(Object param : parameters){
				sb.append("("+(++i)+")"+param.toString()+"\n");
			}			
		}

		logger.info(sb.toString());	
		return null;
	}	
	
	@Around("execution(* com.gm.mygmc.crm.*.service.*.*(..))")
	public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
		
		try {
			return pjp.proceed();
		} catch (Exception ex) {
			logger.error("", ex);
			ResponseDTO responseDTO = new ResponseDTO();
			sb.setLength(0);

			sb.append(ex.getMessage() + "\n");

			distinguishExType(ex, responseDTO);

			logger.info("[ErrorMessage]" + sb.toString());
			responseDTO.setError(true);
			responseDTO.setErrorMessage(sb.toString());
			return responseDTO;
		}
	}

	/**
	 * 辨别异常类型
	 * @param ex
	 * @param responseDTO
	 */
	private void distinguishExType(Exception ex, ResponseDTO responseDTO) {
		if(ex instanceof ConstraintsViolatedException){
			ConstraintViolation[] constraintViolations = ((ConstraintsViolatedException) ex).getConstraintViolations();
			if(constraintViolations != null && constraintViolations.length > 0){
				sb.append("detail message : \n");
				for(ConstraintViolation constraintViolation : constraintViolations){
					sb.append(constraintViolation.getContext()+":"+constraintViolation.getMessage()+";\n");
				}
			}
			responseDTO.setErrorCode("123456");//TODO 规则error code
		}else{
			//TODO 未定义的异常捕获
		}
	}
	
	
}
